/*
 * @Author: lixu lixu@puchigames.com
 * @Date: 2025-06-16 10:37:05
 * @LastEditors: lixu lixu@puchigames.com
 * @LastEditTime: 2025-06-16 10:39:33
 * @FilePath: /go-helper/utils/crypto.go
 * @Description: 加密相关工具函数，包含MD5、SHA系列、HMAC、Base64、Hex等加密和编码功能
 */
package ixUtils

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"io"
	"os"
)

// ---------------------MD5---------------------------------------

// MD5 计算字符串的MD5值
func MD5(str string) string {
	if str == "" {
		return ""
	}
	h := md5.New()
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// MD5Bytes 计算字节数组的MD5值
func MD5Bytes(data []byte) string {
	if len(data) == 0 {
		return ""
	}
	h := md5.New()
	h.Write(data)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// MD5File 计算文件的MD5值
func MD5File(filePath string) (string, error) {
	if filePath == "" {
		return "", fmt.Errorf("file path cannot be empty")
	}
	if !FileExists(filePath) {
		return "", fmt.Errorf("file does not exist: %s", filePath)
	}

	file, err := os.Open(filePath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	h := md5.New()
	if _, err := io.Copy(h, file); err != nil {
		return "", err
	}
	return fmt.Sprintf("%x", h.Sum(nil)), nil
}

// ---------------------SHA---------------------------------------

// SHA1 计算字符串的SHA1值
func SHA1(str string) string {
	if str == "" {
		return ""
	}
	h := sha1.New()
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// SHA1Bytes 计算字节数组的SHA1值
func SHA1Bytes(data []byte) string {
	if len(data) == 0 {
		return ""
	}
	h := sha1.New()
	h.Write(data)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// SHA256 计算字符串的SHA256值
func SHA256(str string) string {
	if str == "" {
		return ""
	}
	h := sha256.New()
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// SHA256Bytes 计算字节数组的SHA256值
func SHA256Bytes(data []byte) string {
	if len(data) == 0 {
		return ""
	}
	h := sha256.New()
	h.Write(data)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// SHA512 计算字符串的SHA512值
func SHA512(str string) string {
	if str == "" {
		return ""
	}
	h := sha512.New()
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// SHA512Bytes 计算字节数组的SHA512值
func SHA512Bytes(data []byte) string {
	if len(data) == 0 {
		return ""
	}
	h := sha512.New()
	h.Write(data)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// ---------------------HMAC---------------------------------------

// HMACMD5 计算字符串的HMAC-MD5值
func HMACMD5(key, str string) string {
	if key == "" {
		return ""
	}
	if str == "" {
		return ""
	}
	h := hmac.New(md5.New, []byte(key))
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// HMACSHA1 计算字符串的HMAC-SHA1值
func HMACSHA1(key, str string) string {
	if key == "" {
		return ""
	}
	if str == "" {
		return ""
	}
	h := hmac.New(sha1.New, []byte(key))
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// HMACSHA256 计算字符串的HMAC-SHA256值
func HMACSHA256(key, str string) string {
	if key == "" {
		return ""
	}
	if str == "" {
		return ""
	}
	h := hmac.New(sha256.New, []byte(key))
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// HMACSHA512 计算字符串的HMAC-SHA512值
func HMACSHA512(key, str string) string {
	if key == "" {
		return ""
	}
	if str == "" {
		return ""
	}
	h := hmac.New(sha512.New, []byte(key))
	io.WriteString(h, str)
	return fmt.Sprintf("%x", h.Sum(nil))
}

// ---------------------Base64---------------------------------------

// Base64Encode Base64编码
func Base64Encode(str string) string {
	if str == "" {
		return ""
	}
	return base64.StdEncoding.EncodeToString([]byte(str))
}

// Base64Decode Base64解码
func Base64Decode(str string) (string, error) {
	if str == "" {
		return "", fmt.Errorf("string cannot be empty")
	}
	bytes, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

// Base64URLEncode URL安全的Base64编码
func Base64URLEncode(str string) string {
	if str == "" {
		return ""
	}
	return base64.URLEncoding.EncodeToString([]byte(str))
}

// Base64URLDecode URL安全的Base64解码
func Base64URLDecode(str string) (string, error) {
	if str == "" {
		return "", fmt.Errorf("string cannot be empty")
	}
	bytes, err := base64.URLEncoding.DecodeString(str)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

// ---------------------Hex---------------------------------------

// HexEncode 十六进制编码
func HexEncode(str string) string {
	if str == "" {
		return ""
	}
	return hex.EncodeToString([]byte(str))
}

// HexDecode 十六进制解码
func HexDecode(str string) (string, error) {
	if str == "" {
		return "", fmt.Errorf("string cannot be empty")
	}
	bytes, err := hex.DecodeString(str)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

// ---------------------Password---------------------------------------

// PasswordHash 密码哈希（使用SHA256）
func PasswordHash(password string) string {
	if password == "" {
		return ""
	}
	return SHA256(password)
}

// PasswordVerify 密码验证
func PasswordVerify(password, hash string) bool {
	if password == "" || hash == "" {
		return false
	}
	return PasswordHash(password) == hash
}
